#ifndef SMART_PTR_H
#define SMART_PTR_H



class RefCounted
{
public:
    template <class T>
    friend class SmartPtr;
    RefCounted() : m_refCount(0) {}
    virtual ~RefCounted(){}

private:
    int m_refCount;
};


template<class T>

class SmartPtr
{
public:
    SmartPtr(T* ptr = 0) : m_ptr(ptr)
    {
        IncrementRef();
    }
    
    ~SmartPtr()
    {
        DecrementRef();
    }

    SmartPtr(const SmartPtr<T>& ptr) : m_ptr(ptr.m_ptr)
    {
        IncrementRef();
    }

    SmartPtr& operator=(const SmartPtr& ptr)
    {
        if(m_ptr == ptr.m_ptr)
        {
            return *this;
        }
        DecrementRef();
        m_ptr = ptr.m_ptr;
        IncrementRef();
        return *this;
    }

    void IncrementRef()
    {
        if(m_ptr)
        {
            ++(m_ptr->m_refCount);
        }
    }

    void DecrementRef()
    {
        if(m_ptr)
        {
            --(m_ptr->m_refCount);
            if(m_ptr->m_refCount == 0)
            {
                delete m_ptr;
            }
        }
    }

    T* operator->() {return m_ptr; }
    operator T*() const {return m_ptr; }

private:
    T* m_ptr;
};

#endif
